from flask import Blueprint, jsonify, request
from applications.models import ArticleCate, Article, db
from bs4 import BeautifulSoup  # 导入 BeautifulSoup
from sqlalchemy import func # 导入 func 用于 count
from flask_sqlalchemy import SQLAlchemy # 导入 SQLAlchemy 用于分页

# 创建故事文章管理蓝图
article_bp = Blueprint('article_bp', __name__, url_prefix='/system')  # 修改 url_prefix

# 辅助函数：构建树形结构
def build_category_tree(categories, parent_id=None):
    tree = []
    for category in categories:
        if category.parent_id == parent_id:
            children = build_category_tree(categories, category.id)
            category_dict = category.to_dict()
            if children:
                category_dict['children'] = children
            tree.append(category_dict)
    return tree

# 获取文章分类列表 (对应前端 getArticleCategoryList)
@article_bp.route('/article-category/list', methods=['POST'])
def get_article_category_list():
    data = request.json
    page = data.get('pageNum', 1)
    page_size = data.get('pageSize', 10)
    category_name = data.get('name', None)
    parent_id = data.get('parentId', None) # 新增按父ID筛选

    query = ArticleCate.query

    if category_name:
        query = query.filter(ArticleCate.name.like(f"%{category_name}%"))
    
    # 如果parent_id为0，表示查询所有顶级分类
    if parent_id is not None and parent_id == 0:
        query = query.filter(ArticleCate.parent_id.is_(None))
    elif parent_id is not None and parent_id > 0:
        query = query.filter(ArticleCate.parent_id == parent_id)

    pagination = query.paginate(page=page, per_page=page_size, error_out=False)
    
    categories_data = [cat.to_list_dict() for cat in pagination.items]

    return jsonify({
        'code': 200,
        'msg': '获取文章分类列表成功',
        'data': categories_data,
        'total': pagination.total,
        'pageSize': page_size,
        'pageNum': page
    }), 200

# 获取文章分类详情 (对应前端 getArticleCategoryDetail)
@article_bp.route('/article-category/detail', methods=['POST'])
def get_article_category_detail():
    data = request.json
    category_id = data.get('id')

    if not category_id:
        return jsonify({'code': 400, 'msg': '缺少分类ID'}), 400

    category = ArticleCate.query.get(category_id)
    if not category:
        return jsonify({'code': 404, 'msg': '分类不存在'}), 404

    return jsonify({
        'code': 200,
        'msg': '获取文章分类详情成功',
        'data': category.to_dict()
    }), 200

# 获取文章分类树形结构 (对应前端 getArticleCategoryTree)
@article_bp.route('/article-category/tree', methods=['GET'])
def get_article_category_tree():
    categories = ArticleCate.query.order_by(ArticleCate.id).all()
    tree = build_category_tree(categories)
    return jsonify({
        'code': 200,
        'msg': '获取文章分类树形结构成功',
        'data': tree
    }), 200

# 添加文章分类 (对应前端 addArticleCategory)
@article_bp.route('/article-category/add', methods=['POST'])
def add_article_category():
    data = request.json
    name = data.get('name')
    parent_id = data.get('parent_id')


    if not name:
        return jsonify({'code': 400, 'msg': '分类名称不能为空'}), 400

    new_category = ArticleCate(name=name, parent_id=parent_id if parent_id else None)
    db.session.add(new_category)
    db.session.commit()
    return jsonify({
        'code': 200,
        'msg': '文章分类添加成功！',
        'data': new_category.to_dict()
    }), 200

# 修改文章分类 (对应前端 updateArticleCategory)
@article_bp.route('/article-category/update', methods=['POST'])
def update_article_category():
    data = request.json
    category_id = data.get('id')
    name = data.get('name')
    parent_id = data.get('parent_id')

    if not category_id:
        return jsonify({'code': 400, 'msg': '缺少分类ID'}), 400
    if not name:
        return jsonify({'code': 400, 'msg': '分类名称不能为空'}), 400

    category = ArticleCate.query.get(category_id)
    if not category:
        return jsonify({'code': 404, 'msg': '分类不存在'}), 404

    category.name = name
    category.parent_id = parent_id if parent_id else None
    db.session.commit()
    return jsonify({
        'code': 200,
        'msg': '分类名称更新成功',
        'data': category.to_dict()
    }), 200

# 删除文章分类 (对应前端 delArticleCategory)
@article_bp.route('/article-category/delete', methods=['POST'])
def del_article_category():
    data = request.json
    category_ids = data.get('ids')  # 预期接收一个ID列表

    if not category_ids:
        return jsonify({'code': 400, 'msg': '缺少分类ID'}), 400

    if not isinstance(category_ids, list):
        category_ids = [category_ids]  # 如果不是列表，转换为列表以便统一处理

    deleted_count = 0
    failed_categories = []

    try:
        for category_id in category_ids:
            category = ArticleCate.query.get(category_id)
            if not category:
                failed_categories.append({'id': category_id, 'reason': '分类不存在'})
                continue

            # 检查是否有子分类
            if category.children:
                failed_categories.append({'id': category_id, 'reason': '该分类下存在子分类，请先删除子分类'})
                continue

            # 检查该分类下是否有文章
            if category.articles:
                failed_categories.append({'id': category_id, 'reason': '该分类下存在文章，请先删除文章'})
                continue

            db.session.delete(category)
            deleted_count += 1
        db.session.commit()

        msg = f'成功删除 {deleted_count} 个故事分类！'
        if failed_categories:
            msg += f' 有 {len(failed_categories)} 个分类未能删除。'
            return jsonify({
                'code': 200,
                'msg': msg,
                'message': msg,
                'failed_categories': failed_categories
            }), 200
        return jsonify({'code': 200, 'msg': msg, 'message': msg}), 200

    except Exception as e:
        db.session.rollback()
        print('删除故事分类时出错:', str(e))
        return jsonify({'code': 500, 'msg': '删除故事分类失败', 'error': str(e)})


#-------------------- 故事文章管理 --------------------
# 获取故事文章列表 (对应前端的 getArticleList，虽然前端没有提供，但后端有类似功能)
@article_bp.route('/article/list', methods=['POST'])
def get_articles():
    data = request.json
    page = data.get('pageNum', 1)
    page_size = data.get('pageSize', 10)
    title_query = data.get('title', '').strip()
    category_id = data.get('category_id', None)
    status = data.get('status', None)

    query = Article.query

    if title_query:
        query = query.filter(Article.title.ilike(f'%{title_query}%'))
    if category_id and category_id > 0:
        query = query.filter(Article.category_id == category_id)
    if status and status in ['0', '1', '2']:
        query = query.filter(Article.status == status)

    pagination = query.paginate(page=page, per_page=page_size, error_out=False)
    articles_data = [article.to_dict() for article in pagination.items]

    return jsonify({
        'code': 200,
        'msg': '获取文章列表成功',
        'data': articles_data,
        'total': pagination.total,
        'pageSize': page_size,
        'pageNum': page
    }), 200

# 添加故事文章 (对应前端 addArticle)
@article_bp.route('/article/add', methods=['POST'])
def add_article():
    data = request.json

    if not isinstance(data, list):
        data = [data] # 允许单个文章或批量文章添加

    try:
        added_articles = []
        for article_data in data:
            if not all(key in article_data for key in ['title', 'content', 'category_id', 'user_id']):
                return jsonify({'code': 400, 'msg': '每个文章对象必须包含 title、content、category_id 和 user_id 字段'}), 400

            category_id_str = article_data['category_id']
            try:
                category_id_int = int(category_id_str)
            except ValueError:
                return jsonify({'code': 400, 'msg': f'无效的分类ID格式: {category_id_str}. ID必须是数字。'}), 400

            category_exists = ArticleCate.query.filter_by(id=category_id_int).first()
            if not category_exists:
                return jsonify({'code': 400, 'msg': f'无效的分类ID: {category_id_int}. 该分类不存在。'}), 400

            new_article = Article(
                user_id=article_data['user_id'],
                title=article_data['title'],
                content=article_data['content'],
                category_id=category_id_int,
                status=article_data.get('status', 'pending'),
                image=article_data.get('image', "/static/index/images/error_ic_404.png"),
                audit_reason=article_data.get('audit_reason', None)
            )
            db.session.add(new_article)
            added_articles.append(new_article)

        db.session.commit()
        return jsonify({
            'code': 200,
            'msg': '故事文章添加成功！',
            'data': [article.to_dict() for article in added_articles]
        }), 200

    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 500, 'msg': f'服务器错误: {str(e)}'}), 500

# 编辑故事文章 (对应前端 updateArticle)
@article_bp.route('/article/update', methods=['POST'])
def update_article():
    data = request.json
    article_id = data.get('id')

    if not article_id:
        return jsonify({'code': 400, 'msg': '缺少文章ID'}), 400

    article = Article.query.get(article_id)
    if not article:
        return jsonify({'code': 404, 'msg': '文章不存在'}), 404

    article.title = data.get('title', article.title)
    article.content = data.get('content', article.content)
    article.category_id = data.get('category_id', article.category_id)
    article.status = data.get('status', article.status)
    article.image = data.get('image', article.image)

    db.session.commit()
    return jsonify({
        'code': 200,
        'msg': '故事文章更新成功！',
        'data': article.to_dict()
    }), 200

# 更新故事文章发布状态 (对应前端 updateArticleStatus)
@article_bp.route('/article/audit', methods=['POST'])
def update_article_status():
    data = request.json
    article_id = data.get('id')
    status = data.get('status')

    if not article_id:
        return jsonify({'code': 400, 'msg': '缺少文章ID'}), 400
    if not status:
        return jsonify({'code': 400, 'msg': '缺少状态参数'}), 400

    try:
        article = Article.query.get(article_id)
        if not article:
            return jsonify({'code': 404, 'msg': '文章不存在'}), 404

        article.status = status
        article.audit_reason = data.get('audit_reason', article.audit_reason)
        db.session.commit()
        return jsonify({
            'code': 200,
            'msg': '文章状态更新成功！',
            'data': article.to_dict()
        }), 200
    except Exception as e:
        db.session.rollback()
        print('更新文章状态失败', e)
        return jsonify({'code': 500, 'msg': '文章状态更新失败', 'error': str(e)})

# 删除故事文章 (对应前端 delArticle)
@article_bp.route('/article/delete', methods=['POST'])
def delete_article():
    data = request.json
    article_ids = data.get('ids')  # 预期接收一个ID列表

    if not article_ids:
        return jsonify({'code': 400, 'msg': '缺少文章ID'}), 400

    if not isinstance(article_ids, list):
        article_ids = [article_ids]  # 如果不是列表，转换为列表以便统一处理

    try:
        deleted_count = 0
        for article_id in article_ids:
            article = Article.query.get(article_id)
            if article:
                db.session.delete(article)
                deleted_count += 1
        db.session.commit()
        return jsonify({'code': 200, 'msg': f'成功删除 {deleted_count} 篇故事文章！'}), 200
    except Exception as e:
        db.session.rollback()
        print('删除故事文章时出错:', str(e))
        return jsonify({'code': 500, 'msg': '删除故事文章失败', 'error': str(e)})

# 注册故事文章管理蓝图
def register_article_bps(app):
    app.register_blueprint(article_bp)
